package top.huntwolf.admin.controller;

import org.apache.shiro.ShiroException;
import org.apache.shiro.authz.AuthorizationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.dao.DataAccessException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import top.huntwolf.admin.common.JsonResult;
import top.huntwolf.admin.common.enums.CodeMsg;
import top.huntwolf.admin.exception.ServiceException;

import java.sql.SQLIntegrityConstraintViolationException;

@RestControllerAdvice
public class ExceptionController {

    private static final Logger log = LoggerFactory.getLogger(ErrorController.class);

    /*拦截未知的运行时异常*/
    @ExceptionHandler(RuntimeException.class)
    public JsonResult handleNotFountException(RuntimeException e){
        log.error("运行时异常: ",e);
        return JsonResult.error(CodeMsg.NOT_FOUNT);
    }

    /*请求方式不支持*/
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public JsonResult handleMethodException(HttpRequestMethodNotSupportedException e){
        log.error(e.getMessage(),e);
        return JsonResult.error(CodeMsg.METHOD_NOT_SUPPORT);
    }

    /*系统异常*/
    @ExceptionHandler({Exception.class})
    public JsonResult handleSystemException(Exception e){
        log.error(e.getMessage(),e);
        return JsonResult.error(CodeMsg.SERVER_ERROR);
    }

    /*校验异常*/
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public JsonResult handleNotValidException(MethodArgumentNotValidException e){
        BindingResult bindingResult = e.getBindingResult();
        String errorMsg = "";
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            errorMsg += fieldError.getDefaultMessage() + "!";
        }
        return JsonResult.error(CodeMsg.BIND_ERROR.fillArgs(errorMsg));
    }

    /*校验异常*/
    @ExceptionHandler({MissingServletRequestParameterException.class})
    public JsonResult handleMissingParamsException(MissingServletRequestParameterException e){
        log.error(e.getMessage(),e);
        return JsonResult.error(CodeMsg.BIND_ERROR.fillArgs("缺少参数:" + e.getParameterName()));
    }

    /*校验异常*/
    @ExceptionHandler(BindException.class)
    public JsonResult handleNotValidException(BindException e){
        BindingResult bindingResult = e.getBindingResult();
        String errorMsg = "";
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            errorMsg += fieldError.getDefaultMessage() + "!";
        }
        return JsonResult.error(CodeMsg.BIND_ERROR.fillArgs(errorMsg));

    }

    /*请求头异常*/
    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    public JsonResult handleHttpMediaTypeException(HttpMediaTypeNotSupportedException e){
        log.error(e.getMessage(),e);
        return JsonResult.error(CodeMsg.CONTENT_TYPE_ERROR.fillArgs(e.getContentType()+"不支持"));
    }

    /*登录异常*/
    @ExceptionHandler(AuthorizationException.class)
    public JsonResult handleLoginException(AuthorizationException e){
        log.error(e.getMessage(),e);
        return JsonResult.error(CodeMsg.SESSION_ERROR);
    }

    /*业务异常*/
    @ExceptionHandler(ServiceException.class)
    public JsonResult handleServiceException(ServiceException e){
        log.error(e.getMessage(),e);
        return JsonResult.error(e.getCodeMsg());
    }

    /*数据库异常*/
    @ExceptionHandler(value = DataAccessException.class)
    @ResponseBody
    public JsonResult repeatException(SQLIntegrityConstraintViolationException e) {
        log.error(e.getMessage(),e);
        return JsonResult.error(CodeMsg.DATABASE_ERROR.fillArgs(e.getMessage()));
    }

    @ExceptionHandler(value = MaxUploadSizeExceededException.class)
    @ResponseBody
    public JsonResult MaxUploadSizeExceededException(MaxUploadSizeExceededException e){
        log.error(e.getMessage(),e);
        return JsonResult.error(CodeMsg.EXCEED_UPLOAD_SIZE);
    }

    @ExceptionHandler(value = NullPointerException.class)
    @ResponseBody
    public JsonResult NullPointerException(NullPointerException e){
        log.error(e.getMessage(),e);
        return JsonResult.error(CodeMsg.SERVER_ERROR.fillArgs("空指针异常"));
    }


}
